<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>Layer Tree Tutorial &mdash; GeoExt v1.0</title>
    <link rel="stylesheet" href="../_static/geoext.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '../',
        VERSION:     '1.0',
        COLLAPSE_MODINDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <link rel="shortcut icon" href="../_static/favicon.ico"/>
    <link rel="top" title="GeoExt v1.0" href="../index.html" />
    <link rel="up" title="Tutorials" href="index.html" />
    <link rel="next" title="Map Tool Tutorial" href="control-button-tutorial.html" />
    <link rel="prev" title="MapPanel Tutorial" href="mappanel-tutorial.html" />
    
    
    
    
    

  </head>
  <body>
    <div class="header">
        <div class="wrap">
            <h1 id="logo"><a href="../index.html">GeoExt</a></h1>
            <ul id="top-nav">
                <li class="first"><a href="../docs.html">Documentation</a></li>
                <li><a href="../examples.html">Examples</a></li>
                <li><a href="../downloads.html">Download</a></li>
                <li><a href="http://trac.geoext.org/">Development</a></li>
            </ul>
            <div id="searchbox">
                <form class="search" action="../search.html" method="get">
                    <input id="searchbox-query" type="text" name="q" size="25" value="Search &hellip;" tabindex="3" onblur="if(this.value=='') this.value='Search &hellip;';" onfocus="if(this.value=='Search &hellip;') this.value='';" />
                    <input id="searchbox-submit" type="image" value="Search" src="../_static/img/search_icon_green.png" />
                    <input type="hidden" name="check_keywords" value="yes" />
                    <input type="hidden" name="area" value="default" />
                </form>
            </div>
        </div>
    </div>

    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li><a href="../index.html">GeoExt</a> &raquo;</li>
          <li><a href="index.html" accesskey="U">Tutorials</a> &raquo;</li>
        <li><a href="#">Layer Tree Tutorial</a></li>
      </ul>
    </div>

      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
            <h3><a href="../index.html">Table Of Contents</a></h3>
            <ul>
<li><a class="reference external" href="#">Layer Tree Tutorial</a><ul>
<li><a class="reference external" href="#start-with-a-map">Start With a Map</a></li>
<li><a class="reference external" href="#filtering">Filtering</a></li>
<li><a class="reference external" href="#visibility-grouping">Visibility Grouping</a></li>
<li><a class="reference external" href="#layer-nodes-with-additional-radio-buttons">Layer Nodes with Additional Radio Buttons</a></li>
<li><a class="reference external" href="#sub-layers">Sub-Layers</a></li>
</ul>
</li>
</ul>

            <h4>Previous topic</h4>
            <p class="topless"><a href="mappanel-tutorial.html"
                                  title="previous chapter"><tt class="docutils literal"><span class="pre">MapPanel</span></tt> Tutorial</a></p>
            <h4>Next topic</h4>
            <p class="topless"><a href="control-button-tutorial.html"
                                  title="next chapter">Map Tool Tutorial</a></p>
        </div>
      </div>


    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
            
  <div class="section" id="layer-tree-tutorial">
<h1>Layer Tree Tutorial<a class="headerlink" href="#layer-tree-tutorial" title="Permalink to this headline">¶</a></h1>
<p>Often when presenting users with an interactive map, it is useful to allow them
to control the visible layers. In this tutorial, we examine the use of
<a title="GeoExt.tree.LayerContainer" class="reference external" href="../lib/GeoExt/widgets/tree/LayerContainer.html#GeoExt.tree.LayerContainer"><tt class="xref docutils literal"><span class="pre">GeoExt.tree.LayerContainer</span></tt></a> with the stock <tt class="docutils literal"><span class="pre">Ext.tree.TreePanel</span></tt> class
to accommodate toggling visibility of layers and rearranging their drawing
order.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Before starting this tutorial, you should have a working
<a title="GeoExt.MapPanel" class="reference external" href="../lib/GeoExt/widgets/MapPanel.html#GeoExt.MapPanel"><tt class="xref docutils literal"><span class="pre">GeoExt.MapPanel</span></tt></a> in your page. The <a class="reference external" href="mappanel-tutorial.html"><em>MapPanel Tutorial</em></a> will
help you set one up if you don&#8217;t already have one.</p>
</div>
<div class="section" id="start-with-a-map">
<h2>Start With a Map<a class="headerlink" href="#start-with-a-map" title="Permalink to this headline">¶</a></h2>
<p>Let&#8217;s assume you already have a <a title="GeoExt.MapPanel" class="reference external" href="../lib/GeoExt/widgets/MapPanel.html#GeoExt.MapPanel"><tt class="xref docutils literal"><span class="pre">GeoExt.MapPanel</span></tt></a> on your page with some
layers. In the <a class="reference external" href="mappanel-tutorial.html"><em>MapPanel Tutorial</em></a>, we discussed how you can use the
<tt class="docutils literal"><span class="pre">layers</span></tt> property of the <tt class="docutils literal"><span class="pre">MapPanel</span></tt> to add, remove, and modify the layers of
the map as well as monitor the layer list for changes. This is more than
sufficient to display a &#8216;live&#8217; list of layers in an <tt class="docutils literal"><span class="pre">Ext.grid.GridPanel</span></tt>.
The <a title="GeoExt.tree.LayerContainer" class="reference external" href="../lib/GeoExt/widgets/tree/LayerContainer.html#GeoExt.tree.LayerContainer"><tt class="xref docutils literal"><span class="pre">GeoExt.tree.LayerContainer</span></tt></a> is another component that can listen to
changes to the map&#8217;s layer list. However, rather than an independent panel, the
<tt class="docutils literal"><span class="pre">LayerContainer</span></tt> is a node that must be contained in an <tt class="docutils literal"><span class="pre">Ext.tree.TreePanel</span></tt>
to be displayed. Here&#8217;s an example rendering a layer tree to a <tt class="docutils literal"><span class="pre">div</span></tt>:</p>
<div class="highlight-javascript"><div class="highlight"><pre><span class="kd">var</span> <span class="nx">mapPanel</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">GeoExt</span><span class="p">.</span><span class="nx">MapPanel</span><span class="p">({</span>
    <span class="cm">/* Your configuration here */</span>
<span class="p">});</span>

<span class="kd">var</span> <span class="nx">layerList</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">GeoExt</span><span class="p">.</span><span class="nx">tree</span><span class="p">.</span><span class="nx">LayerContainer</span><span class="p">({</span>
    <span class="nx">text</span><span class="o">:</span> <span class="s1">&#39;All Layers&#39;</span><span class="p">,</span>
    <span class="nx">layerStore</span><span class="o">:</span> <span class="nx">mapPanel</span><span class="p">.</span><span class="nx">layers</span><span class="p">,</span>
    <span class="nx">leaf</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
    <span class="nx">expanded</span><span class="o">:</span> <span class="kc">true</span>
<span class="p">});</span>

<span class="kd">var</span> <span class="nx">layerTree</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Ext</span><span class="p">.</span><span class="nx">tree</span><span class="p">.</span><span class="nx">TreePanel</span><span class="p">({</span>
    <span class="nx">title</span><span class="o">:</span> <span class="s1">&#39;Map Layers&#39;</span><span class="p">,</span>
    <span class="nx">renderTo</span><span class="o">:</span> <span class="s1">&#39;layerTree&#39;</span><span class="p">,</span>
    <span class="nx">root</span><span class="o">:</span> <span class="nx">layerList</span>
<span class="p">});</span>
</pre></div>
</div>
<p><tt class="docutils literal"><span class="pre">LayerContainer</span></tt>s automatically add checkboxes (radio buttons for base
layers) that can be used to toggle the visibility of layers. You can also enable
drag-n-drop layer reordering by simply setting the <tt class="docutils literal"><span class="pre">enableDD</span></tt> property of the
<tt class="docutils literal"><span class="pre">TreePanel</span></tt>.</p>
</div>
<div class="section" id="filtering">
<h2>Filtering<a class="headerlink" href="#filtering" title="Permalink to this headline">¶</a></h2>
<p>By default, the <tt class="docutils literal"><span class="pre">LayerContainer</span></tt>&#8216;s <tt class="docutils literal"><span class="pre">LayerLoader</span></tt> automatically pulls in all layers from the store and displays those with the <tt class="docutils literal"><span class="pre">displayInLayerSwitcher</span></tt>
property set to true. You can provide your own filter function to the loader:</p>
<div class="highlight-javascript"><div class="highlight"><pre><span class="kd">var</span> <span class="nx">layerList</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">GeoExt</span><span class="p">.</span><span class="nx">tree</span><span class="p">.</span><span class="nx">LayerContainer</span><span class="p">({</span>
    <span class="nx">text</span><span class="o">:</span> <span class="s1">&#39;Tasmania Layers&#39;</span><span class="p">,</span>
    <span class="nx">layerStore</span><span class="o">:</span> <span class="nx">mapPanel</span><span class="p">.</span><span class="nx">layers</span><span class="p">,</span>
    <span class="nx">leaf</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
    <span class="nx">expanded</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
    <span class="nx">loader</span><span class="o">:</span> <span class="p">{</span>
        <span class="nx">filter</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">record</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="nx">record</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;layer&quot;</span><span class="p">).</span><span class="nx">name</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s2">&quot;Tasmania&quot;</span><span class="p">)</span> <span class="o">!==</span> <span class="o">-</span><span class="mi">1</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">});</span>
</pre></div>
</div>
<p>The above will only load layers with &#8220;Tasmania&#8221; in their name. By adding
multiple named and filtered <tt class="docutils literal"><span class="pre">LayerContainer</span></tt>s to a <tt class="docutils literal"><span class="pre">TreePanel</span></tt> you are
able to provide logical organization to your layer trees. When <tt class="docutils literal"><span class="pre">enableDD</span></tt> is
set to true on the tree, drag-n-drop will also work between filtered layer
containers, as long as they have the same parent node. You can also directly
instantiate <a title="GeoExt.tree.LayerNode" class="reference external" href="../lib/GeoExt/widgets/tree/LayerNode.html#GeoExt.tree.LayerNode"><tt class="xref docutils literal"><span class="pre">GeoExt.tree.LayerNode</span></tt></a> to create tree nodes that can be
added anywhere in a tree. Keep in mind, however, that this approach does not
allow for automatic drag-n-drop support.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p>There are two LayerContainer types with a preconfigured filter:</p>
<ul class="last simple">
<li><a title="GeoExt.tree.BaseLayerContainer" class="reference external" href="../lib/GeoExt/widgets/tree/BaseLayerContainer.html#GeoExt.tree.BaseLayerContainer"><tt class="xref docutils literal"><span class="pre">GeoExt.tree.BaseLayerContainer</span></tt></a> will be populated only with layers
that have isBaseLayer set to true,</li>
<li><a title="GeoExt.tree.OverlayLayerContainer" class="reference external" href="../lib/GeoExt/widgets/tree/OverlayLayerContainer.html#GeoExt.tree.OverlayLayerContainer"><tt class="xref docutils literal"><span class="pre">GeoExt.tree.OverlayLayerContainer</span></tt></a> will be populated only with
layers that have  isBaseLayer set to false.</li>
</ul>
</div>
</div>
<div class="section" id="visibility-grouping">
<h2>Visibility Grouping<a class="headerlink" href="#visibility-grouping" title="Permalink to this headline">¶</a></h2>
<p>The concept of a base layer in OpenLayers is just a gruop of layers that are on
the bottom of the layer stack, and only one can be visible at a time. In maps
without base layers (when <tt class="docutils literal"><span class="pre">allOverlays</span></tt> is set to true, the latter can be
enforced by configuring a <tt class="docutils literal"><span class="pre">checkedGroup</span></tt> on a LayerNode. Such a layer node
will be rendered with a radio button instead of a check box. Of all layers
configured with the same <tt class="docutils literal"><span class="pre">checkedGroup</span></tt>, only one will be visible at a time:</p>
<div class="highlight-javascript"><div class="highlight"><pre><span class="kd">var</span> <span class="nx">layerList</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">GeoExt</span><span class="p">.</span><span class="nx">tree</span><span class="p">.</span><span class="nx">LayerContainer</span><span class="p">({</span>
    <span class="nx">text</span><span class="o">:</span> <span class="s1">&#39;Tasmania Layers&#39;</span><span class="p">,</span>
    <span class="nx">layerStore</span><span class="o">:</span> <span class="nx">mapPanel</span><span class="p">.</span><span class="nx">layers</span><span class="p">,</span>
    <span class="nx">leaf</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
    <span class="nx">expanded</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
    <span class="nx">loader</span><span class="o">:</span> <span class="p">{</span>
        <span class="nx">filter</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">record</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="nx">record</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;layer&quot;</span><span class="p">).</span><span class="nx">name</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s2">&quot;Tasmania&quot;</span><span class="p">)</span> <span class="o">!==</span> <span class="o">-</span><span class="mi">1</span>
        <span class="p">},</span>
        <span class="nx">baseAttrs</span><span class="o">:</span> <span class="p">{</span>
            <span class="nx">checkedGroup</span><span class="o">:</span> <span class="s2">&quot;tasmania&quot;</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">});</span>
</pre></div>
</div>
</div>
<div class="section" id="layer-nodes-with-additional-radio-buttons">
<h2>Layer Nodes with Additional Radio Buttons<a class="headerlink" href="#layer-nodes-with-additional-radio-buttons" title="Permalink to this headline">¶</a></h2>
<p>It is possible to render layer nodes with an additional radio button. This can
be useful if an application uses the concept of an &#8220;active layer&#8221;. The active
layer can then be set by clicking its radio button:</p>
<div class="highlight-javascript"><div class="highlight"><pre><span class="kd">var</span> <span class="nx">layerList</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">GeoExt</span><span class="p">.</span><span class="nx">tree</span><span class="p">.</span><span class="nx">LayerContainer</span><span class="p">({</span>
    <span class="nx">text</span><span class="o">:</span> <span class="s1">&#39;All Layers&#39;</span><span class="p">,</span>
    <span class="nx">layerStore</span><span class="o">:</span> <span class="nx">mapPanel</span><span class="p">.</span><span class="nx">layers</span><span class="p">,</span>
    <span class="nx">leaf</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
    <span class="nx">expanded</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
    <span class="nx">loader</span><span class="o">:</span> <span class="p">{</span>
        <span class="nx">baseAttrs</span><span class="o">:</span> <span class="p">{</span>
            <span class="nx">radioGroup</span><span class="o">:</span> <span class="s2">&quot;active&quot;</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">});</span>
<span class="kd">var</span> <span class="nx">registerRadio</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span>
    <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">node</span><span class="p">.</span><span class="nx">hasListener</span><span class="p">(</span><span class="s2">&quot;radiochange&quot;</span><span class="p">))</span> <span class="p">{</span>
        <span class="nx">node</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s2">&quot;radiochange&quot;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">node</span><span class="p">){</span>
            <span class="cm">/* set your active layer here */</span>
        <span class="p">});</span>
    <span class="p">}</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">layerTree</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Ext</span><span class="p">.</span><span class="nx">tree</span><span class="p">.</span><span class="nx">TreePanel</span><span class="p">({</span>
    <span class="nx">title</span><span class="o">:</span> <span class="s1">&#39;Map Layers&#39;</span><span class="p">,</span>
    <span class="nx">renderTo</span><span class="o">:</span> <span class="s1">&#39;layerTree&#39;</span><span class="p">,</span>
    <span class="nx">root</span><span class="o">:</span> <span class="nx">layerList</span><span class="p">,</span>
    <span class="nx">listeners</span><span class="o">:</span> <span class="p">{</span>
        <span class="nx">append</span><span class="o">:</span> <span class="nx">registerRadio</span><span class="p">,</span>
        <span class="nx">insert</span><span class="o">:</span> <span class="nx">registerRadio</span>
    <span class="p">}</span>
<span class="p">});</span>
</pre></div>
</div>
<p>The layer node fires the &#8220;radiochange&#8221; event when the radio button is clicked.
The above snippet configures a listener for this event when a node is added to
or inserted in the tree.</p>
</div>
<div class="section" id="sub-layers">
<h2>Sub-Layers<a class="headerlink" href="#sub-layers" title="Permalink to this headline">¶</a></h2>
<p>Layers that have a <tt class="docutils literal"><span class="pre">params</span></tt> property (like <tt class="docutils literal"><span class="pre">OpenLayers.Layer.WMS</span></tt>) can be
used to create sub-layers based on one of the <tt class="docutils literal"><span class="pre">params</span></tt> properties. This is
useful to e.g. create sub-nodes from the layer object&#8217;s &#8220;LAYERS&#8221; or &#8220;CQL_FILTER&#8221;
param:</p>
<div class="highlight-javascript"><div class="highlight"><pre><span class="kd">var</span> <span class="nx">groupLayer</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">OpenLayers</span><span class="p">.</span><span class="nx">Layer</span><span class="p">.</span><span class="nx">WMS</span><span class="p">(</span><span class="s2">&quot;Tasmania (Group Layer)&quot;</span><span class="p">,</span>
    <span class="s2">&quot;http://demo.opengeo.org/geoserver/wms&quot;</span><span class="p">,</span> <span class="p">{</span>
        <span class="nx">layers</span><span class="o">:</span> <span class="p">[</span>
            <span class="s2">&quot;topp:tasmania_state_boundaries&quot;</span><span class="p">,</span>
            <span class="s2">&quot;topp:tasmania_water_bodies&quot;</span><span class="p">,</span>
            <span class="s2">&quot;topp:tasmania_cities&quot;</span><span class="p">,</span>
            <span class="s2">&quot;topp:tasmania_roads&quot;</span>
        <span class="p">],</span>
        <span class="nx">transparent</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
        <span class="nx">format</span><span class="o">:</span> <span class="s2">&quot;image/gif&quot;</span>
    <span class="p">}</span>
<span class="p">);</span>
<span class="kd">var</span> <span class="nx">groupLayerNode</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">GeoExt</span><span class="p">.</span><span class="nx">tree</span><span class="p">.</span><span class="nx">LayerNode</span><span class="p">({</span>
    <span class="nx">layer</span><span class="o">:</span> <span class="nx">groupLayer</span><span class="p">,</span>
    <span class="nx">leaf</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
    <span class="nx">expanded</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
    <span class="nx">loader</span><span class="o">:</span> <span class="p">{</span>
        <span class="nx">param</span><span class="o">:</span> <span class="s2">&quot;LAYERS&quot;</span>
    <span class="p">}</span>
<span class="p">});</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">The <a title="GeoExt.tree.LayerParamLoader" class="reference external" href="../lib/GeoExt/widgets/tree/LayerParamLoader.html#GeoExt.tree.LayerParamLoader"><tt class="xref docutils literal"><span class="pre">GeoExt.tree.LayerParamLoader</span></tt></a> does not add drag-n-drop support
to the sub-nodes it creates, so <tt class="docutils literal"><span class="pre">allowDrag</span></tt> and <tt class="docutils literal"><span class="pre">allowDrag</span></tt> should be
set to false for a <a title="GeoExt.tree.LayerNode" class="reference external" href="../lib/GeoExt/widgets/tree/LayerNode.html#GeoExt.tree.LayerNode"><tt class="xref docutils literal"><span class="pre">GeoExt.tree.LayerNode</span></tt></a> configured with a
<tt class="xref docutils literal"><span class="pre">GeoExt.class.LayerParamLoader</span></tt>, unless you provide custom &#8220;move&#8221;
handlers.</p>
</div>
<div class="admonition-see-also admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">The ExtJS TreePanel <a class="reference external" href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.tree.TreePanel">documentation</a> and <a class="reference external" href="http://dev.sencha.com/deploy/dev/examples/#sample-7">examples</a> for more
information about customizing tree panels.</p>
</div>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
            <li class="right" style="margin-right: 10px">
              <a href="../genindex.html" title="General Index"
                 accesskey="I">index</a></li>
            <li class="right" >
              <a href="../modindex.html" title="Global Module Index"
                 accesskey="M">modules</a> |</li>
            <li class="right" >
              <a href="control-button-tutorial.html" title="Map Tool Tutorial"
                 accesskey="N">next</a> |</li>
            <li class="right" >
              <a href="mappanel-tutorial.html" title="MapPanel Tutorial"
                 accesskey="P">previous</a> |</li>
        <li><a href="../index.html">GeoExt</a> &raquo;</li>
          <li><a href="index.html" >Tutorials</a> &raquo;</li>
        <li><a href="#">Layer Tree Tutorial</a></li>
      </ul>
    </div>

    <div class="footer">
      &copy; Copyright 2009-2010, GeoExt Community.
    </div>
  </body>
</html>